﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;

namespace WickedFlame.VecDraw.Base.Controls
{
    [TemplatePart(Name = "PART_PopUp", Type = typeof(Popup)), TemplatePart(Name = "PART_TransparentSelector", Type = typeof(Border)), TemplatePart(Name = "PART_SwatchCanvas", Type = typeof(Canvas)), TemplatePart(Name="PART_Button", Type=typeof(Border))]
	public class ColorSelector : ContentControl
	{
		//public event RoutedEventHandler ColorChanged;

		Popup popup;
		Border transparentselector;
        Button button;
		Canvas swatchcanvas;

		static ColorSelector()
        {
			DefaultStyleKeyProperty.OverrideMetadata(typeof(ColorSelector), new FrameworkPropertyMetadata(typeof(ColorSelector)));
        }

        public override void OnApplyTemplate()
        {
            if (transparentselector != null)
            {
                transparentselector.MouseLeftButtonUp -= new System.Windows.Input.MouseButtonEventHandler(TransparentSelector_MouseLeftButtonUp);
                transparentselector = null;
            }

            if (swatchcanvas != null)
            {
                swatchcanvas.MouseLeftButtonUp -= new System.Windows.Input.MouseButtonEventHandler(Swatch_MouseLeftButtonUp);
                swatchcanvas = null;
            }

            if (button != null)
            {
                button.Click -= new RoutedEventHandler(button_Click);
                button = null;
            }

            base.OnApplyTemplate();

            popup = GetTemplateChild("PART_PopUp") as Popup;

            transparentselector = GetTemplateChild("PART_TransparentSelector") as Border;
            if (transparentselector != null)
                transparentselector.MouseLeftButtonUp += new System.Windows.Input.MouseButtonEventHandler(TransparentSelector_MouseLeftButtonUp);

            swatchcanvas = GetTemplateChild("PART_SwatchCanvas") as Canvas;
            if(swatchcanvas!= null)
                swatchcanvas.MouseLeftButtonUp += new System.Windows.Input.MouseButtonEventHandler(Swatch_MouseLeftButtonUp);

            button = GetTemplateChild("PART_Button") as Button;
            if(button!= null)
                button.Click += new RoutedEventHandler(button_Click);
        }

        void button_Click(object sender, RoutedEventArgs e)
        {
            if (popup != null)
                popup.IsOpen = true;
        }

        void Swatch_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            try
            {
                var ColorImage = ((Image)SwatchImage).Source as BitmapSource;

                CroppedBitmap cb = new CroppedBitmap(ColorImage,
                    new Int32Rect((int)Mouse.GetPosition(swatchcanvas).X,
                        (int)Mouse.GetPosition(swatchcanvas).Y, 1, 1));

                byte[] pixels = new byte[4];

                try
                {
                    cb.CopyPixels(pixels, 4, 0);
                }
                catch { }

                SelectedColor = Color.FromArgb((byte)255, pixels[2], pixels[1], pixels[0]);

                if (popup != null)
                    popup.IsOpen = false;
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.Write(ex.Message);
            }
        }

        void TransparentSelector_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            SelectedColor = Colors.Transparent;
            if (popup != null)
                popup.IsOpen = false;
        }

        #region Dependencie Properties

        public Color SelectedColor
        {
            get
            {
                return (Color)GetValue(SelectedColorProperty);
            }
			set
			{
				SetValue(SelectedColorProperty, value);
			}
        }

        public static readonly DependencyProperty SelectedColorProperty =
			DependencyProperty.Register("SelectedColor", typeof(Color), typeof(ColorSelector),
			new FrameworkPropertyMetadata(Colors.Transparent, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, 
			new PropertyChangedCallback(OnSelectedValueChanged)));

		protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
		{
			base.OnPropertyChanged(e);
			DependencyProperty prop = e.Property;
			if (prop == ColorSelector.SelectedColorProperty)
			{
				this.SelectedColor = (Color)e.NewValue;
			}
		}

		private static void OnSelectedValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
		{
		}

        public bool IsTransparentVisible
        {
            get
            {
                return (bool)GetValue(IsTransparentVisibleProperty);
            }
            set
            {
                SetValue(IsTransparentVisibleProperty, value);
            }
        }

        public static readonly DependencyProperty IsTransparentVisibleProperty =
            DependencyProperty.Register("IsTransparentVisible", typeof(bool), typeof(ColorSelector), new PropertyMetadata(true));

        public object SwatchImage
        {
            get
            {
                return (object)GetValue(SwatchImageProperty);
            }
            set
            {
                SetValue(SwatchImageProperty, value);
            }
        }

        public static readonly DependencyProperty SwatchImageProperty =
            DependencyProperty.Register("SwatchImage", typeof(object), typeof(ColorSelector), new FrameworkPropertyMetadata(null, new CoerceValueCallback(OnCoerce_Icon)));

        private static object OnCoerce_Icon(DependencyObject o, object value)
        {
            if (value is string)
            {
                Uri iconUri;
                // try to resolve given value as an absolute URI
                if (Uri.TryCreate(value as String, UriKind.RelativeOrAbsolute, out iconUri))
                {
                    ImageSource img = new BitmapImage(iconUri);
                    if (null != img)
                    {
                        Image icon = (o as ColorSelector).SwatchImage as Image;
                        if (null == icon)
                            icon = new Image();

                        icon.Source = img;
                        icon.Stretch = Stretch.None;
                        icon.SnapsToDevicePixels = true;

                        return icon;
                    }
                }
            }
            return value;
        }

        #endregion
    }
}
